// noinspection JSUnresolvedVariable

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { requireResolve } = require('./utils');
const webpack = require('webpack');

const config = require(requireResolve('jjb.config.json'));
const packageJSON = require(requireResolve('package.json'));
const server = (config.server || {});
const framework = (config.framework || {});
const environment = (config.environment || {})[ process.env.NODE_ENV ];
const windowInject = {
  ...(config.windowInject || {}),
  ...environment,
  framework
};
const contextInject = (config.contextInject || {});
const contextData = {
  ...environment,
  ...contextInject
};

module.exports = mode => {
  const isProduction = mode === 'production';
  return {
    server,
    webpack: {
      // 模式 ‘development’ | ‘production’
      mode,
      // 入口
      entry: './src/index.js',
      // 输出
      output: {
        libraryTarget: 'umd',
        // 指定输出目录文件名
        path: path.resolve(__dirname, '../dist'),
        // 定义全局变量,暴露到‘window’对象中
        library: packageJSON.name,
        // 指定编译的‘js’存放目录文件名称
        filename: 'index.js',
        // 输出公共路径
        publicPath: '/'
      },
      // ‘node.module’
      module: {
        // 文件处理
        rules: [
          {
            // 处理‘less’和‘css’文件
            test: /\.(less|css)$/,
            // 以此从下到上处理‘css’
            use: [
              // 3:由‘webpack.MiniCssExtractPlugin.loader’做收尾工作
              // 主要分离css文件
              {
                loader: 'style-loader'
              },
              // {
              //   loader: MiniCssExtractPlugin.loader
              // },
              // 2:将被‘less-loader’处理的‘css’
              // 由‘css-loader’再次处理
              {
                loader: 'css-loader'
              },
              // 1:处理‘less’文件
              {
                // 使用‘less-loader’
                loader: 'less-loader',
                // 配置‘less-loader’
                options: {
                  // ‘less-loader’特殊配置
                  lessOptions: {
                    // 定义‘less’全局变量,从jjb.config.antd获取
                    modifyVars: (framework || {}).antd || {},
                    // 启用‘less-javascript’功能
                    javascriptEnabled: true
                  }
                }
              }
            ]
          },
          {
            // 处理‘js’文件
            test: /\.js$/,
            // 使用‘babel-loader’
            loader: 'babel-loader',
            // 允许‘babel-loader’操作目录
            include: [
              // 整个‘src’目录
              path.resolve(__dirname, '../src')
            ],
            // 配置‘babel-loader’
            options: {
              // 加入一个‘babel-plugin-import’插件,特殊处理‘antd’文件过大问题
              plugins: [
                [
                  'import',
                  {
                    // ‘webpack’定义全局变量‘antd’
                    libraryName: 'antd',
                    // 按需将‘es’文件夹中组件导出,绑定到‘antd’变量
                    // 除了‘es’,也可以修改为‘lib’
                    libraryDirectory: 'es',
                    // 这里设为‘true’,表示自动导入‘antd/dist/less’
                    // 或修改为‘css’ | ‘less’
                    style: true
                  }
                ],
                [
                  '@babel/plugin-proposal-decorators',
                  {
                    'legacy': true
                  }
                ]
              ],
              // 考虑到使用‘React JSX’语法‘babel-loader’的编译预设要改为‘preset-react’
              // 可选值‘preset-env’
              presets: [ '@babel/preset-react' ]
            }
          },
          {
            // 处理‘svg’文件
            test: /\.svg/,
            // 使用‘file-loader’
            loader: 'url-loader',
            // 配置‘file-loader’
            options: {
              limit: true
            }
          },
          {
            // 处理图片文件
            test: /\.(png|jpg|jpeg|gif|ico|bmp)/,
            // 使用‘url-loader’或‘raw-loader’
            loader: 'url-loader',
            // 配置‘url-loader’
            options: {
              limit: true
            }
          }
        ]
      },
      // 解析
      resolve: {
        // 为‘import’或‘require’定义别名路径
        alias: {
          '~': requireResolve('src')
        }
      },
      // 插件
      plugins: [
        // 定义输出‘html’模板
        // 并向‘window’全局注入变量
        !isProduction
          ? new HtmlWebpackPlugin(Object.assign({ template: requireResolve('public/index.html') }, windowInject))
          : null,
        // 对分离的‘css’区块定义同步导入名称,和异步导入名称
        // new MiniCssExtractPlugin({
        //   // 同步导入‘import | require’
        //   filename: 'static/css/[id].css',
        //   // 异步导入‘import | require’
        //   chunkFilename: 'static/css/[id].css'
        // }),
        // 注入全局变量到项目中,从‘jjb.config.contextData’读取
        new webpack.DefinePlugin({ 'process.env.app': JSON.stringify(contextData) }),
        // 解决‘moment.js’本地化文件过多问题
        // 按需加载本地化文件当前项目只需要‘zh_CN.js’
        new webpack.IgnorePlugin({
          contextRegExp: /moment$/,
          resourceRegExp: /^\.\/locale$/
        }),
        // 每次打包前删除‘dist’目录
        new CleanWebpackPlugin()
      ].filter(value => !!value),
      // 外部扩展
      externals: {
        'jjb-common-lib-types': 'jjbCommonLib',
        ...(isProduction
          ? {
            'react': 'React',
            'react-dom': 'ReactDOM'
          }
          : {})
      }
    }
  };
};
